#include <process.h>
#include <windows.h>
#include "sfc_thread.h"

static unsigned __stdcall SfThreadEntry(void* arg) {
    TSfThread* thread = (TSfThread*)arg;
    
    if (thread->OnExecute) {
        return thread->OnExecute(thread);
    } else if (thread->OnRunOnce) {
        while (!thread->terminated_) {
            int delay = thread->OnRunOnce(thread);
            if (delay > 0) {
                Sleep(delay);
            }
        }
    }
    return 0;
}

Bool TSfThreadCreate(TSfThread* self, TSfThreadPriority priority, void* stack, Int32 stack_size) {
    // 检查堆栈8字节对齐
    if ((uintptr_t)stack % 8 != 0) {
        return False;
    }
    
    self->stack_ = stack;
    self->stack_size_ = stack_size;
    self->priority_ = priority;
    return True;
}

Bool TSfThreadCreateEx(TSfThread* self, const TSfThreadAttr* attr) {
    if (attr) {
        if (attr->name) {
            strncpy(self->name_, attr->name, sizeof(self->name_)-1);
        }
        return TSfThreadCreate(self, attr->priority, attr->stack, attr->stack_size);
    }
    return TSfThreadCreate(self, kSfThreadPriorityNormal, NULL, 0);
}

void TSfThreadDestroy(TSfThread *self)
{
    if (self->handle_) {
        CloseHandle(self->handle_);
        self->handle_ = NULL;
    }
}

Bool TSfThreadResume(TSfThread* self) {
    unsigned threadId;
    self->handle_ = (HANDLE)_beginthreadex(
        NULL,
        self->stack_size_,
        SfThreadEntry,
        self,
        CREATE_SUSPENDED,
        &threadId
    );
    
    if (self->handle_) {
        // 设置线程优先级映射
        int winPriority = THREAD_PRIORITY_NORMAL;
        switch (self->priority_) {
            case kSfThreadPriorityLow: winPriority = THREAD_PRIORITY_LOWEST; break;
            case kSfThreadPriorityBelowNormal: winPriority = THREAD_PRIORITY_BELOW_NORMAL; break;
            case kSfThreadPriorityNormal: winPriority = THREAD_PRIORITY_NORMAL; break;
            case kSfThreadPriorityAboveNormal: winPriority = THREAD_PRIORITY_ABOVE_NORMAL; break;
            case kSfThreadPriorityHigh: winPriority = THREAD_PRIORITY_HIGHEST; break;
            case kSfThreadPriorityRealtime: winPriority = THREAD_PRIORITY_TIME_CRITICAL; break;
        }
        SetThreadPriority(self->handle_, winPriority);
        
        ResumeThread(self->handle_);
        return True;
    }
    return False;
}

void TSfThreadTerminate(TSfThread* self) {
    self->terminated_ = True;
}

Bool TSfThreadTerminated(TSfThread *self)
{
    return self->terminated_;
}

Bool TSfThreadWaitFor(TSfThread* self, UInt32 timeout) {
    if (WaitForSingleObject(self->handle_, timeout) == WAIT_OBJECT_0) {
        CloseHandle(self->handle_);
        self->handle_ = NULL;
        return True;
    }
    return False;
}